#include <optional>
#include <nice2d/util.h>
#include <nice2d/entity.h>
#include <nice2d/actions/rotateaction.h>

class RotateActionData
{
public:
    RotateDirection direction;
    float oldAngle = 0.0f;
    float rotateAngle = 0.0f;
    std::optional<float> velocity;
};

RotateAction::RotateAction(RotateDirection direction, float duration):
    FiniteTimeAction(duration),
    data(new RotateActionData)
{
    data->direction = direction;
}

RotateAction::~RotateAction()
{
}

void RotateAction::setRotate(float angle)
{
    data->rotateAngle = angle;
}

void RotateAction::update(float deltaTime)
{
    if (getOwner().expired())
        return;

    auto target = std::dynamic_pointer_cast<Entity>(getOwner().lock());

    if (!data->velocity.has_value()) {
        data->oldAngle = target->getRotate();
        if (data->direction == RotateDirection_Left)
            data->velocity = (-data->rotateAngle) / getDuration();
        else
            data->velocity = (data->rotateAngle) / getDuration();
    }

    auto newAngle = target->getRotate() + data->velocity.value() * deltaTime;
    target->setRotate(newAngle);

    float diff = std::fabs(newAngle - data->oldAngle);
    if (isEqual(diff, 360.0f - data->rotateAngle, 1.0f) || isEqual(diff, data->rotateAngle, 1.0f)) {
        if (data->direction == RotateDirection_Left)
            target->setRotate(data->oldAngle - data->rotateAngle);
        else
            target->setRotate(data->oldAngle + data->rotateAngle);
        stop();
    }
}
